unit unit_AppSettings;
interface
uses
  SysUtils,
  Classes,
  Dialogs,
  IniFiles,
  StrUtils,
  Forms,
  FileCtrl,
  //
  // my units
  //
  unit_GenesisLocalRepository,
  unit_SettingsConsts
  ;
type
  TOutputDirMode = (omOutputRootDir, omNativeDir);
  TUnpackDirMode = (umRootDir, umArcNameDir, umDigitsDir);
  TProcessMode = (pmUnpack, pmNormal, pmError, pmEncrypted, pmMultiVolume);
  //
  TURLServer = record
    TemplateURL: AnsiString;
    MinID: integer;
    MaxID: integer;
  end;
  TURLServers = array of TURLServer;

type
  //============================================================================
  // TAppSettings class
  //    Class for store application settings and save them into ini-file
  //============================================================================
  TAppSettings = class
  private
    //--------------------------------------------------------------------------
    // ini-file variable to store app settings and it filename
    //--------------------------------------------------------------------------
    FIniFile: TIniFile;
    FINIFileName: AnsiString;
    //
    // System paths section
    //
    FAppDir: AnsiString;
    FCheckFinishID: Integer;
    FTempDir: AnsiString;
    //
    // Local repositories parameters
    //
    FRepositories: TRepositories;
    FRepositoriesCount: Integer;
    //
    // Genesis DB parameters
    //
    FGenesisDBConnectString: AnsiString;
    FGenesisDBPassword: Integer;
    FGenesisDBUserName: AnsiString;
    //
    // Filter options
    //
    FFieldsDelimiter: AnsiChar;
    FGenesisCSVFile: AnsiString;
    FGenesisFilePathDelimiter: AnsiChar;
    FGenesisFieldDelimiter: AnsiChar;    
    //
    // Web repositories parameters
    //
    FServers: TURLServers;
    FServersCount: Integer;
    //
    // Process options fields
    //
    FCheckStartID: Integer;
    FConvertPathesToRelative: Boolean;

    FAutoLoadLocalDBDump: Boolean;
    FLocalDBDumpFile: AnsiString;
    FRelativeRootLevel: Integer;
    FAutoSaveLocalDBDump: Boolean;
    FCollectionFilesChecks: TCheckState;
    FExtraFilesChecks: TCheckState;
    FExtraRepositoryRoot: AnsiString;
    FLocalFilesChecks: TCheckState;
    FOutdatedRepositoryRoot: AnsiString;
    FProcessExtraFiles: Boolean;
    FProcessLocalFiles: Boolean;
    FSelectFilter: AnsiString;
    //
    // Log processing fields
    //
    FLogCreateErrorID: Boolean;
    FLogCreateExistFiles: Boolean;
    FLogCreateExtraFiles: Boolean;
    FLogCreateErrorFileSize: Boolean;
    FLogCreateErrorMD5: Boolean;
    FLogCreateMissedFiles: Boolean;
    FLogCreateMissedFilesURL: Boolean;
    FLogCreateOutdatedFiles: Boolean;
    FLogFileErrorID: AnsiString;
    FLogFileErrorMD5: AnsiString;
    FLogFileMissedFiles: AnsiString;
    FLogFileOutdatedFiles: AnsiString;
    FLogFileErrorFileSize: AnsiString;
    FLogFileMissedFilesURL: AnsiString;
    FLogFileExistFiles: AnsiString;
    FLogFileExtraFiles: AnsiString;
    procedure SetCollectionFilesChecks(const Value: TCheckState);
    procedure SetExtraFilesChecks(const Value: TCheckState);
    procedure SetExtraRepositoryRoot(const Value: AnsiString);
    procedure SetLogFileExtraFiles(const Value: AnsiString);
    //--------------------------------------------------------------------------
    // properties initialization  routines
    //--------------------------------------------------------------------------
    procedure SetRepositories(Value: TRepositories);
    procedure SetServers(const Value: TURLServers);
    procedure SetServersCount(Value: Integer);
    procedure SetGenesisDBPassword(const Value: Integer);
    procedure SetLocalDBDumpFile(const Value: AnsiString);
    procedure SetLocalFilesChecks(const Value: TCheckState);
    procedure SetLogCreateErrorID(const Value: Boolean);
    procedure SetLogCreateExistFiles(const Value: Boolean);
    procedure SetLogCreateExtraFiles(const Value: Boolean);
    procedure SetLogCreateErrorFileSize(const Value: Boolean);
    procedure SetLogCreateErrorMD5(const Value: Boolean);
    procedure SetLogCreateMissedFiles(const Value: Boolean);
    procedure SetLogCreateMissedFilesURL(const Value: Boolean);
    procedure SetLogCreateOutdatedFiles(const Value: Boolean);
    procedure SetLogFileErrorID(const Value: AnsiString);
    procedure SetLogFileErrorMD5(const Value: AnsiString);
    procedure SetLogFileMissedFiles(const Value: AnsiString);
    procedure SetOutdatedRepositoryRoot(const Value: AnsiString);
    procedure SetProcessExtraFiles(const Value: Boolean);
    procedure SetProcessLocalFiles(const Value: Boolean);
    procedure SetRelativeRootLevel(const Value: Integer);
    procedure SetRepositoriesCount(Value: integer);
    procedure SetSelectFilter(const Value: AnsiString);
    //
  protected
    //--------------------------------------------------------------------------
    // internal pathes processing subroutines
    //--------------------------------------------------------------------------
    function ConvertToAbsolutePath(const RelPath: AnsiString): AnsiString;
    function ConvertToRelativePath(const AbsPath: AnsiString): AnsiString;
    //--------------------------------------------------------------------------
    // Load|save settings routines
    //--------------------------------------------------------------------------
    function GetSettingsFileName: AnsiString;
    //
    procedure LoadGeneralAppSettings;
    procedure SaveGeneralAppSettings;
    //
    procedure LoadLocalRepositoriesSettings;
    procedure SaveLocalRepositoriesSettings;
    //
    procedure LoadExtraRepositoriesSettings;
    procedure SaveExtraRepositorySettings;
    //
    procedure LoadOutdatedRepositoriesSettings;
    procedure SaveOutdatedRepositorySettings;
    //
    procedure LoadWebServersSettings;
    procedure SaveWebRepositoriesSettings;
    //
    procedure LoadCheckFileSettings;
    procedure SaveCheckFileSettings;
    //
    procedure LoadGenesisFilelistSettings;
    procedure SaveGenesisFilelistSettings;
    //
    procedure LoadLogFilesSettings;
    procedure SaveLogFilesSettings;
    //
    // Supplementary subset processing functions
    //
    function LoadCheckState(const SectionName, ParamName: AnsiString; const
        DefValue: Integer): TCheckState;
    procedure SaveCheckState(const SectionName, ParamName: AnsiString; const Value:
        TCheckState);
    //
    function LoadParameter(var Buf; const ParamRecord: TParamRecord):
        Boolean;
    //
    property SelectFilter: AnsiString read FSelectFilter write SetSelectFilter;
    //
  public
    //--------------------------------------------------------------------------
    // Global ini file properties
    //--------------------------------------------------------------------------
    property IniFileName: AnsiString read FINIFileName;
    //
    // General application properties
    //
    property AppDir: AnsiString read FAppDir;
    property TempDir: AnsiString read FTempDir write FTempDir;
    property ConvertPathesToRelative: Boolean read FConvertPathesToRelative write
        FConvertPathesToRelative;
    property RelativeRootLevel: Integer read FRelativeRootLevel write
        SetRelativeRootLevel;
    //
    // Web repository parameters
    //
    property Servers: TURLServers read FServers write SetServers;
    property ServersCount: Integer read FServersCount write SetServersCount;
    //
    // Local repository parameters
    //
    property Repositories: TRepositories read FRepositories write
        SetRepositories;
    property RepositoriesCount: Integer read FRepositoriesCount write
        SetRepositoriesCount;
    //
    // Extra repository parameters
    //
    property ExtraRepositoryRoot: AnsiString read FExtraRepositoryRoot write
        SetExtraRepositoryRoot;
    //
    // Outdated repository parameters
    //
    property OutdatedRepositoryRoot: AnsiString read FOutdatedRepositoryRoot write
        SetOutdatedRepositoryRoot;
    //
    // Local in-memory database properties
    //
    property AutoLoadLocalDBDump: Boolean read FAutoLoadLocalDBDump write
        FAutoLoadLocalDBDump;
    property AutoSaveLocalDBDump: Boolean read FAutoSaveLocalDBDump write
        FAutoSaveLocalDBDump;
    property LocalDBDumpFile: AnsiString read FLocalDBDumpFile write
        SetLocalDBDumpFile;
    //
    // Genesis filelist parameters
    //
    property GenesisCSVFile: AnsiString read FGenesisCSVFile write FGenesisCSVFile;
    property GenesisFilePathDelimiter: AnsiChar read FGenesisFilePathDelimiter
        write FGenesisFilePathDelimiter;
    property GenesisFieldDelimiter: AnsiChar read FGenesisFieldDelimiter write
        FGenesisFieldDelimiter;
    //
    // Genesis database parameters
    //
    property GenesisDBConnectString: AnsiString read FGenesisDBConnectString write
        FGenesisDBConnectString;
    property GenesisDBPassword: Integer read FGenesisDBPassword write
        SetGenesisDBPassword;
    property GenesisDBUserName: AnsiString read FGenesisDBUserName write
        FGenesisDBUserName;
    //
    // Process options
    //
    property LocalFilesChecks: TCheckState read FLocalFilesChecks write
        SetLocalFilesChecks;
    property ExtraFilesChecks: TCheckState read FExtraFilesChecks write
        SetExtraFilesChecks;
    //
    property CheckStartID: Integer read FCheckStartID write FCheckStartID;
    property CheckFinishID: Integer read FCheckFinishID write FCheckFinishID;
    //
    property CollectionFilesChecks: TCheckState read FCollectionFilesChecks write
        SetCollectionFilesChecks;

    //
    // Result log files parameters
    //
    property LogFileErrorFileSize: AnsiString read FLogFileErrorFileSize write
        FLogFileErrorFileSize;
    property LogCreateErrorFileSize: Boolean read FLogCreateErrorFileSize write
        SetLogCreateErrorFileSize;
    //
    property LogFileErrorMD5: AnsiString read FLogFileErrorMD5 write
        SetLogFileErrorMD5;
    property LogCreateErrorMD5: Boolean read FLogCreateErrorMD5 write
        SetLogCreateErrorMD5;
    //
    property LogFileMissedFilesURL: AnsiString read FLogFileMissedFilesURL write
        FLogFileMissedFilesURL;
    property LogCreateMissedFilesURL: Boolean read FLogCreateMissedFilesURL write
        SetLogCreateMissedFilesURL;
    //
    property LogFileExtraFiles: AnsiString read FLogFileExtraFiles write
        SetLogFileExtraFiles;
    property LogCreateExtraFiles: Boolean read FLogCreateExtraFiles write
        SetLogCreateExtraFiles;
    //
    property LogFileExistFiles: AnsiString read FLogFileExistFiles write
        FLogFileExistFiles;
    property LogCreateExistFiles: Boolean read FLogCreateExistFiles write
        SetLogCreateExistFiles;
    //
    property LogFileMissedFiles: AnsiString read FLogFileMissedFiles write
        SetLogFileMissedFiles;
    property LogCreateMissedFiles: Boolean read FLogCreateMissedFiles write
        SetLogCreateMissedFiles;
    //
    property LogFileErrorID: AnsiString read FLogFileErrorID write
        SetLogFileErrorID;
    property LogCreateErrorID: Boolean read FLogCreateErrorID write
        SetLogCreateErrorID;
    //
    property LogFileOutdatedFiles: AnsiString read FLogFileOutdatedFiles write
        FLogFileOutdatedFiles;
    property LogCreateOutdatedFiles: Boolean read FLogCreateOutdatedFiles write
        SetLogCreateOutdatedFiles;
    property ProcessExtraFiles: Boolean read FProcessExtraFiles write
        SetProcessExtraFiles;
    property ProcessLocalFiles: Boolean read FProcessLocalFiles write
        SetProcessLocalFiles;
    //--------------------------------------------------------------------------
    // TAppSettings public class routines
    //--------------------------------------------------------------------------
    function LoadSettings: Boolean;
    procedure SaveSettings;
    //
    function SelectDir(var SelectedDir: AnsiString; DialogCaption: AnsiString = '';
        RootDir: AnsiString = '\'; const CanCreateDir: Boolean = True): Boolean;
    function SelectFile(var FileName: AnsiString; DialogCaption: AnsiString = '';
        RootDir: AnsiString = '\'; const CanCreateFile: Boolean = True): Boolean;
    //--------------------------------------------------------------------------
    // General class functions - constructor, destructor, etc
    //--------------------------------------------------------------------------
    constructor Create (IniFileName: AnsiString = '');
    destructor Destroy;
  end;
  //----------------------------------------------------------------------------
  // functions for create/destroy Settings variable from main application
  //   and get access to it
  //----------------------------------------------------------------------------
  procedure CreateAppSettings;
  procedure FreeAppSettings;
  function Settings: TAppSettings;
//==============================================================================
// Implementation unit section
//==============================================================================
implementation
const
  APP_SETTINGS_INIFILENAME = 'settings.ini';
var
  g_objSettings: TAppSettings;
//------------------------------------------------------------------------------
// procedure CreateAppSettings;
//   Create exemplar of TAppSettings unique application variable
// Parameters:
//   None
// Result:
//   None
//------------------------------------------------------------------------------
procedure CreateAppSettings;
begin
  Assert(not Assigned(g_objSettings));
  //
  if not Assigned(g_objSettings) then
    g_objSettings := TAppSettings.Create;
end;
//------------------------------------------------------------------------------
// procedure FreeAppSettings;
//   Free used memory and destroy exemplar of TAppSettings main variable
// Parameters:
//   None
// Result:
//   None
//------------------------------------------------------------------------------
procedure FreeAppSettings;
begin
  Assert(Assigned(g_objSettings));
  //
  FreeAndNil(g_objSettings);
end;
//------------------------------------------------------------------------------
// function Settings
//   Returns link to exemplar of TAppSettings class
// Parameters:
//   None
// Result (TAppSettings):
//   link to exemplar of TAppSettings class, or nil if it don't exists
//------------------------------------------------------------------------------
function Settings: TAppSettings;
begin
  Assert(Assigned(g_objSettings));

  Result := g_objSettings;
end;
//------------------------------------------------------------------------------
// constructor TAppSettings.Create
//   Create exemplar of TAppSettings class, initialize internal class variables
// Parameters:
//   IniFileName: TFileName - ini-file with application settings
// Result:
//   None
//------------------------------------------------------------------------------
constructor TAppSettings.Create(IniFileName: AnsiString = '');
begin
  inherited Create;
  // Initialize path variables
  FAppDir := ExtractFilePath(Application.ExeName);
  FTempDir := FAppDir + '$tmp';
  ForceDirectories(FTempDir);
  // Initialize FIniFileName variable
  if (IniFileName = '') or (not FileExists(IniFileName)) then begin
    FIniFileName := FAppDir + APP_SETTINGS_INIFILENAME;
  end
  else begin
    FINIFileName := INIFileName;
  end;

  LoadSettings;
//  // Create exemplar of TINIFile
//  FIniFile := TIniFile.Create(IniFileName);
end;
//------------------------------------------------------------------------------
// Destructor TAppSettings.Destroy
//   Free resources and destroy exemplar of class TAppSettings
// Parameters:
//   None
// Result:
//   None
//------------------------------------------------------------------------------
destructor TAppSettings.Destroy;
begin
  FIniFile.Free;        FIniFile := nil;

  inherited;
end;

//------------------------------------------------------------------------------
// function TAppSettings.ConvertToAbsolutePath
//   Convert relative filepath to absolute filepath
// Parameters:
//   const RelPath: AnsiString - input filepath (relative or absolute)
// Result: AnsiString
//   Absolute filepath to file
//------------------------------------------------------------------------------
function TAppSettings.ConvertToAbsolutePath(const RelPath: AnsiString):
    AnsiString;
var
  nRootLevel: integer;
  nRootDirPos: integer;
  cResult: AnsiString;
  cAppDir: AnsiString;
begin
  cResult := RelPath;
  //
  // Initialize work pathes variables and process all supported level of convertion
  //
  nRootLevel := 0;
  cAppDir := ExcludeTrailingPathDelimiter(Self.AppDir);
  while nRootLevel < Length(REL_PATH_TEMPLATE) do begin
    //
    // Check if dir template present in filepath. If True, replace it
    //   by absolute directory path and exit convertion cycle
    //
    if REL_PATH_TEMPLATE[nRootLevel] = EmptyStr then begin
      //
      // Get previous root directory level and check next root level
      //
      Inc(nRootLevel);
      cAppDir := ExcludeTrailingPathDelimiter(ExtractFileDir(cAppDir));
      Continue;
    end;
    nRootDirPos := Pos(REL_PATH_TEMPLATE[nRootLevel], cResult);
    if nRootDirPos > 0 then begin
      cResult := AnsiReplaceStr(cResult, REL_PATH_TEMPLATE[nRootLevel], cAppDir);
      Break;
    end;
    //
    // Get previous root directory level and check next root level
    //
    Inc(nRootLevel);
    cAppDir := ExcludeTrailingPathDelimiter(ExtractFileDir(cAppDir));
  end;
  //
  // Set result and exit function
  //
  Result := cResult;
end;
//------------------------------------------------------------------------------
// function TAppSettings.ConvertToRelativePath
//   Convert absolute filepath to relative filepath
// Parameters:
//   const AbsPath: AnsiString - input absolute filepath
// Result: AnsiString
//   Relative filepath, if convertion can be applied;
//     otherwise, initial absolute filepath
//------------------------------------------------------------------------------
function TAppSettings.ConvertToRelativePath(const AbsPath: AnsiString):
    AnsiString;
var
  nRootLevel: integer;
  cRootDir: AnsiString;
  nRootDirPos: Integer;
  cResult: AnsiString;
begin
  //
  // initialize work variables. Assign to temp variable app root dir (level 0)
  //
  cRootDir := ExcludeTrailingPathDelimiter(Self.AppDir);
  cResult := AbsPath;
  //
  // process all specified root levels and try to convert path to relative
  //
  for nRootLevel := 0 to FRelativeRootLevel  do begin
    //
    // Check if dir template present in filepath. If True, replace it
    //   by absolute directory path and exit convertion cycle
    //
    nRootDirPos := Pos(cRootDir, cResult);
    if nRootDirPos > 0 then begin
      cResult := AnsiReplaceStr(cResult, cRootDir, REL_PATH_TEMPLATE[nRootLevel]);
      Break;
    end;
    //
    // Get previous root directory level
    //
    cRootDir := ExcludeTrailingPathDelimiter(ExtractFileDir(cRootDir));
  end;
  //
  // Set result and exit function
  //
  Result := cResult;
end;

//------------------------------------------------------------------------------
// TAppSettings.GetSettingsFileName function
//   Returns settings ini-file filename
// Parameters:
//   None
// Result (TFileName):
//   Filename of settings ini-file
//------------------------------------------------------------------------------
function TAppSettings.GetSettingsFileName: AnsiString;
begin
  Result := FINIFileName;
end;
//------------------------------------------------------------------------------
// procedure TAppSettings.LoadGenesisFilelistSettings
//   Internal for routine TAppSettings.LoadSettings only
//   Load genesis filelist related parameters values
// Parameters:
//   None
// Result:
//   None
//------------------------------------------------------------------------------
procedure TAppSettings.LoadGenesisFilelistSettings;
var
  cParamValue: AnsiString;
begin
  FGenesisCSVFile := ConvertToAbsolutePath(FIniFile.ReadString(
    SECTION_GENESIS_FILELIST, GENESIS_FILELIST_NAME, GENESIS_FILELIST_NAME_DEF));
  FLocalDBDumpFile := ConvertToAbsolutePath(FIniFile.ReadString(
    SECTION_GENESIS_FILELIST, GENESIS_LOCAL_DB_DUMP_FILENAME,
    GENESIS_LOCAL_DB_DUMP_FILENAME_DEF));
  //
  // Load input file fields' delimiter value.
  //   Process special case for tab delimiter
  //
  cParamValue := FIniFile.ReadString(SECTION_GENESIS_FILELIST,
    GENESIS_FIELD_DELIMITER, GENESIS_FIELD_DELIMITER_DEF);
  if UpperCase(cParamValue) = TAB_DELIMITER_STRING  then cParamValue := #9;
  FGenesisFieldDelimiter := cParamValue[1];
  //
  FGenesisFilePathDelimiter := FIniFile.ReadString(SECTION_GENESIS_FILELIST,
    GENESIS_FILEPATH_DELIMITER, GENESIS_FILEPATH_DELIMITER_DEF)[1];
end;
//------------------------------------------------------------------------------
// procedure TAppSettings.LoadLocalRepositoriesSettings
//   Internal to TAppSettings.LoadSettings routine
//     Load local repositories parameters
// Parameters:
//   None
// Result:
//   None
//------------------------------------------------------------------------------
procedure TAppSettings.LoadLocalRepositoriesSettings;
var
  nRepIndex: integer;
  //
  cRepPath: AnsiString;
  nRepMinID: integer;
  nRepMaxID: integer;
begin
  //
  // Get stored repositories count, initialize storage variables
  //
  FRepositoriesCount := FIniFile.ReadInteger(SECTION_LOCAL_REPOSITORY,
    REPOSITORIES_COUNT, REPOSITORIES_COUNT_DEF);
  SetLength(FRepositories, FRepositoriesCount);
  //
  // Load repositories info
  //
  for nRepIndex := 0 to FRepositoriesCount - 1 do begin
    cRepPath := FIniFile.ReadString(SECTION_LOCAL_REPOSITORY,
      REPOSITORY_PATH_TEMPLATE + IntToStr(nRepIndex+1), REPOSITORY_PATH_DEF);
    cRepPath := ConvertToAbsolutePath(cRepPath);
    nRepMinID := FIniFile.ReadInteger(SECTION_LOCAL_REPOSITORY,
      REPOSITORY_MIN_ID_TEMPLATE + IntToStr(nRepIndex+1), REPOSITORY_MIN_ID_DEF);
    nRepMaxID := FIniFile.ReadInteger(SECTION_LOCAL_REPOSITORY,
      REPOSITORY_MAX_ID_TEMPLATE + IntToStr(nRepIndex+1), REPOSITORY_MAX_ID_DEF);
    //
    with FRepositories[nRepIndex] do begin
      BaseDir := IncludeTrailingPathDelimiter(cRepPath);
      MinID := nRepMinID;
      MaxID := nRepMaxID;
    end;
  end;
end;
//------------------------------------------------------------------------------
// procedure TAppSettings.LoadWebServersSettings
//   Internal to TAppSettings.LoadSettings. Get output directory parameters values
// Parameters:
//   None
// Result:
//   None
//------------------------------------------------------------------------------
procedure TAppSettings.LoadWebServersSettings;
var
  nSrvIndex: integer;
  //
  cSrvTemplateURL: AnsiString;
  nSrvMinID: integer;
  nSrvMaxID: integer;
begin
  //
  // Get web servers count, initialize storage variables
  //
  FServersCount := FIniFile.ReadInteger(SECTION_WEB_REPOSITORY,
    SERVERS_COUNT, SERVERS_COUNT_DEF);
  SetLength(FServers, FServersCount);
  //
  // Load web servers info
  //
  for nSrvIndex := 0 to FServersCount - 1 do begin
    cSrvTemplateURL := FIniFile.ReadString(SECTION_WEB_REPOSITORY,
      SERVER_TEMPLATE_URL + IntToStr(nSrvIndex+1), SERVER_TEMPLATE_URL_DEF);
    nSrvMinID := FIniFile.ReadInteger(SECTION_WEB_REPOSITORY,
      SERVER_MIN_ID_TEMPLATE + IntToStr(nSrvIndex+1), SERVER_MIN_ID_DEF);
    nSrvMaxID := FIniFile.ReadInteger(SECTION_WEB_REPOSITORY,
      SERVER_MAX_ID_TEMPLATE + IntToStr(nSrvIndex+1), SERVER_MAX_ID_DEF);
    //
    with FServers[nSrvIndex] do begin
      TemplateURL := cSrvTemplateURL;
      MinID := nSrvMinID;
      MaxID := nSrvMaxID;
    end;
  end;
end;
//------------------------------------------------------------------------------
// TAppSettings.LoadGeneralAppSettings
//   Internal for routine TAppSettings.LoadSettings only
//     Load input|output pathes parameters
// Parameters:
//   None
// Result:
//   None
//------------------------------------------------------------------------------
procedure TAppSettings.LoadGeneralAppSettings;
begin
  //
  // Load application process mode variables
  //
  FAppDir := ExtractFilePath(Application.ExeName);
  FConvertPathesToRelative := FIniFile.ReadBool(SECTION_GENERAL_SETTINGS,
    CONVERT_PATHES_TO_RELATIVE, CONVERT_PATHES_TO_RELATIVE_DEF);
  FRelativeRootLevel := FIniFile.ReadInteger(SECTION_GENERAL_SETTINGS,
    RELATIVE_CONVERSION_LEVEL, RELATIVE_CONVERSION_LEVEL_DEF);
  //
  // Load directories variables directories. Convert relative pathes, if presents
  //   always process all pathes to check if they are relative
  //
  FTempDir := FIniFile.ReadString(SECTION_GENERAL_SETTINGS, TEMP_DIR,
    TEMP_DIR_DEF);
  FTempDir := ConvertToAbsolutePath(FTempDir);
  //
  // Load application on start load|save db local flags
  //
  FAutoLoadLocalDBDump := FIniFile.ReadBool(SECTION_GENERAL_SETTINGS,
    AUTOLOAD_LOCAL_DB_DUMP, AUTOLOAD_LOCAL_DB_DUMP_DEF);
  FAutoSaveLocalDBDump := FIniFile.ReadBool(SECTION_GENERAL_SETTINGS,
    AUTOSAVE_LOCAL_DB_DUMP, AUTOSAVE_LOCAL_DB_DUMP_DEF);
end;
//------------------------------------------------------------------------------
// procedure TAppSettings.LoadCheckFileSettings
//  Internal for routine TAppSettings.LoadSettings only
//    Load process files settings
// Parameters:
//   None
// Result:
//   None
//------------------------------------------------------------------------------
procedure TAppSettings.LoadCheckFileSettings;
begin
  //
  // Read process options variables values
  //
  FProcessLocalFiles :=
    FIniFile.ReadBool(SECTION_CHECK_OPTIONS, PROCESS_LOCAL_FILES, PROCESS_LOCAL_FILES_DEF);
  FProcessExtraFiles := FIniFile.ReadBool(SECTION_CHECK_OPTIONS, PROCESS_EXTRA_FILES,
    PROCESS_EXTRA_FILES_DEF);
  //
  // Read processed id range
  //
  FCheckStartID := FIniFile.ReadInteger(SECTION_CHECK_OPTIONS,
    OPTION_CHECK_START_ID, OPTION_CHECK_START_ID_DEF);
  FCheckFinishID := FIniFile.ReadInteger(SECTION_CHECK_OPTIONS,
    OPTION_CHECK_FINISH_ID, OPTION_CHECK_FINISH_ID_DEF);
  //
  // Read specified files' checks
  //
  FLocalFilesChecks := LoadCheckState(SECTION_CHECK_OPTIONS,
      OPTION_LOCAL_FILES_CHECKS, OPTION_LOCAL_FILES_CHECKS_DEF);
  FExtraFilesChecks := LoadCheckState(SECTION_CHECK_OPTIONS,
      OPTION_EXTRA_FILES_CHECKS, OPTION_EXTRA_FILES_CHECKS_DEF);
end;
//------------------------------------------------------------------------------
// TAppSettings.LoadCheckState
//    Read check state information from ini-file and convert it to TCheckState
// Parameters:
//   const SectionName : AnsiString - ini-file section name
//   const ParamName : AnsiString   - parameter name
//   const DefValue : Integer       - default parameter value (integer)
// Result: TCheckState
//   Specified parameter, converted to TCheckState
//------------------------------------------------------------------------------
function TAppSettings.LoadCheckState(const SectionName, ParamName: AnsiString;
    const DefValue: Integer): TCheckState;
var
  xCheck: TCheckCondition;
  nCheckState: integer;
  nCheckMask: Integer;
  //
  i, nMinState, nMaxState: Integer;
begin
  Result := [];
  //
  // Load data from ini-file in numerical format
  //
  nCheckState := FIniFile.ReadInteger(SectionName, ParamName, DefValue);
  //
  // Convert data to TCheckState variable and exit
  //
  nMinState := Integer(Low(TCheckCondition));
  nMaxState := Integer(High(TCheckCondition));
  for i := nMinState to nMaxState do begin
    nCheckMask := 1 shl i;
    if (nCheckState and nCheckMask) = nCheckMask then
      Result := Result +[TCheckCondition(i)];
  end;
end;
//------------------------------------------------------------------------------
// procedure TAppSettings.LoadExtraRepositoriesSettings
//   Internal to routine TAppSettings.LoadSettings only.
//   Load extra repository related parameters
// Parameters:
//   None
// Result:
//   None
//------------------------------------------------------------------------------
procedure TAppSettings.LoadExtraRepositoriesSettings;
begin
  FExtraRepositoryRoot := ConvertToAbsolutePath(FIniFile.ReadString(
    SECTION_EXTRA_REPOSITORY, REPOSITORY_ROOT, REPOSITORY_ROOT_DEF));

end;
//------------------------------------------------------------------------------
// procedure TAppSettings.LoadLogFilesSettings
//   Internal to routine TAppSettings.LoadSettings only.
//   Load result filelists related parameters
// Parameters:
//   None
// Result:
//   None
//------------------------------------------------------------------------------
procedure TAppSettings.LoadLogFilesSettings;
begin
  //
  // Log file for files with
  //
  FLogFileExistFiles := ConvertToAbsolutePath(FIniFile.ReadString(
    SECTION_LOG_FILES, LOG_FILE_EXIST_FILES, LOG_FILE_EXIST_FILES_DEF));
  FLogCreateExistFiles := FIniFile.ReadBool(SECTION_LOG_FILES,
    LOG_CREATE_EXIST_FILES, LOG_CREATE_EXIST_FILES_DEF);
  //
  FLogFileOutdatedFiles := ConvertToAbsolutePath(FIniFile.ReadString(
    SECTION_LOG_FILES, LOG_FILE_OUTDATED_FILES, LOG_FILE_OUTDATED_FILES_DEF));
  FLogCreateOutdatedFiles := FIniFile.ReadBool(SECTION_LOG_FILES,
    LOG_CREATE_OUTDATED_FILES, LOG_CREATE_OUTDATED_FILES_DEF);
  //
  FLogFileMissedFiles := ConvertToAbsolutePath(FIniFile.ReadString(
    SECTION_LOG_FILES, LOG_FILE_MISSED_FILES, LOG_FILE_MISSED_FILES_DEF));
  FLogCreateMissedFiles := FIniFile.ReadBool(SECTION_LOG_FILES,
    LOG_CREATE_MISSED_FILES, LOG_CREATE_MISSED_FILES_DEF);
  //
  FLogFileErrorFileSize := ConvertToAbsolutePath(FIniFile.ReadString(SECTION_LOG_FILES,
    LOG_FILE_ERROR_FILESIZE, LOG_FILE_ERROR_FILESIZE_DEF));
  FLogCreateErrorFileSize := FIniFile.ReadBool(SECTION_LOG_FILES,
    LOG_CREATE_ERROR_FILESIZE, LOG_CREATE_ERROR_FILESIZE_DEF);
  //
  FLogFileErrorMD5 := ConvertToAbsolutePath(FIniFile.ReadString(SECTION_LOG_FILES,
    LOG_FILE_ERROR_MD5, LOG_FILE_ERROR_MD5_DEF));
  FLogCreateErrorMD5 := FIniFile.ReadBool(SECTION_LOG_FILES,
    LOG_CREATE_ERROR_MD5, LOG_CREATE_ERROR_MD5_DEF);
  //
  FLogFileMissedFilesURL := ConvertToAbsolutePath(FIniFile.ReadString(SECTION_LOG_FILES,
    LOG_FILE_MISSED_FILES_URLLIST, LOG_FILE_MISSED_FILES_URLLIST_DEF));
  FLogCreateMissedFilesURL := FIniFile.ReadBool(SECTION_LOG_FILES,
    LOG_CREATE_MISSED_FILES_URLLIST, LOG_CREATE_MISSED_FILES_URLLIST_DEF);
  //
  FLogFileExtraFiles := ConvertToAbsolutePath(FIniFile.ReadString(SECTION_LOG_FILES,
    LOG_FILE_EXTRA_FILES, LOG_FILE_EXTRA_FILES_DEF));
  FLogCreateExtraFiles := FIniFile.ReadBool(SECTION_LOG_FILES,
    LOG_CREATE_EXTRA_FILES, LOG_CREATE_EXTRA_FILES_DEF);
  //
  FLogFileErrorID := ConvertToAbsolutePath(FIniFile.ReadString(SECTION_LOG_FILES,
    LOG_FILE_ERROR_ID, LOG_FILE_ERROR_ID_DEF));
  FLogCreateErrorID := FIniFile.ReadBool(SECTION_LOG_FILES,
    LOG_CREATE_ERROR_ID, LOG_CREATE_ERROR_ID_DEF);
end;
//------------------------------------------------------------------------------
// procedure TAppSettings.LoadOutdatedRepositoriesSettings
//   Internal to routine TAppSettings.LoadSettings only.
//   Load outdated repository related parameters
// Parameters:
//   None
// Result:
//   None
//------------------------------------------------------------------------------
procedure TAppSettings.LoadOutdatedRepositoriesSettings;
begin
  FOutdatedRepositoryRoot := ConvertToAbsolutePath(FIniFile.ReadString(
    SECTION_OUTDATED_REPOSITORY, REPOSITORY_ROOT, REPOSITORY_ROOT_DEF));
end;

function TAppSettings.LoadParameter(var Buf; const ParamRecord: TParamRecord
    ): Boolean;
begin
  Result := False;
  //
  // Process 
  //
  case ParamRecord.ParamType of
    ptInteger: begin

    end;
    ptBoolean: begin

    end;
    ptAnsiString: begin
    
    end;
  else
    //;
  end;
end;
//------------------------------------------------------------------------------
// function TAppSettings.LoadSettings
//   Load application settings from predefined ini-file
// Parameters:
//   None
// Result:
//   True, if settings load is successful, False otherwise
//------------------------------------------------------------------------------
function TAppSettings.LoadSettings: Boolean;
begin
  //
  // if FINIFile already loaded, destroy it and create new instance
  //
  if FIniFile <> nil then begin
    FIniFile.Free;      FIniFile := nil;
  end;
  //
  // Load app settings from ini-file
  //
  try
    //
    // Load TIniFile variable from specified ini-file
    //
    FIniFile := TIniFile.Create(GetSettingsFileName);
    //
    // Load path settings
    //
    LoadGeneralAppSettings;
    //
    // Load local repositories settings
    //
    LoadLocalRepositoriesSettings;
    //
    // Load extra repositories settings
    //
    LoadExtraRepositoriesSettings;
    //
    // Load outdated repositories settings
    //
    LoadOutdatedRepositoriesSettings;
    //
    // Load web repositories settings
    //
    LoadWebServersSettings;
    //
    // Load process options
    //
    LoadCheckFileSettings;
    //
    // Load genesis filelist settings
    //
    LoadGenesisFilelistSettings;
    //
    // Load result log files settings
    //
    LoadLogFilesSettings;
  finally
    FIniFile.Free;        FIniFile := nil;
  end;
end;
//------------------------------------------------------------------------------
// procedure TAppSEttings.SaveGenesisFilelistSettings
//   Internal to routine TAppSettings.SaveSettings only.
//   Save genesis filelist related parameters
// Parameters:
//   None
// Result:
//   None
//------------------------------------------------------------------------------
procedure TAppSettings.SaveGenesisFilelistSettings;
begin
  FIniFile.WriteString(SECTION_GENESIS_FILELIST, GENESIS_FILELIST_NAME,
    ConvertToRelativePath(FGenesisCSVFile));
  FIniFile.WriteString(SECTION_GENESIS_FILELIST, GENESIS_LOCAL_DB_DUMP_FILENAME,
    ConvertToRelativePath(FLocalDBDumpFile));
  //
  // Save input file delimiter information. Process special case for Tab delimiter
  //
  if FGenesisFieldDelimiter = TAB_DELIMITER  then 
    FIniFile.WriteString(SECTION_GENESIS_FILELIST, GENESIS_FIELD_DELIMITER,
      TAB_DELIMITER_STRING)
  else
    FIniFile.WriteString(SECTION_GENESIS_FILELIST, GENESIS_FIELD_DELIMITER,
      FGenesisFieldDelimiter);
  //
  FIniFile.WriteString(SECTION_GENESIS_FILELIST, GENESIS_FILEPATH_DELIMITER,
    FGenesisFilePathDelimiter);
end;
//------------------------------------------------------------------------------
// procedure TAppSettings.SaveLocalRepositoriesSettings
//   Internal routine for procedure TAppSettings.SaveSettings
//     Save local repositories settings
// Parameters:
//   None
// Result:
//   None
//------------------------------------------------------------------------------
procedure TAppSettings.SaveLocalRepositoriesSettings;
var
  nRepIndex: integer;
begin
  //
  // Save repositories count, initialize storage variables
  //
  FIniFile.WriteInteger(SECTION_LOCAL_REPOSITORY, REPOSITORIES_COUNT,
    FRepositoriesCount);
  //
  // Save repositories info
  //
  for nRepIndex := 0 to FRepositoriesCount - 1 do begin
    FIniFile.WriteString(SECTION_LOCAL_REPOSITORY, REPOSITORY_PATH_TEMPLATE +
      IntToStr(nRepIndex+1), ConvertToAbsolutePath(FRepositories[nRepIndex].BaseDir));
    FIniFile.WriteInteger(SECTION_LOCAL_REPOSITORY, REPOSITORY_MIN_ID_TEMPLATE +
      IntToStr(nRepIndex+1), FRepositories[nRepIndex].MinID);
    FIniFile.WriteInteger(SECTION_LOCAL_REPOSITORY, REPOSITORY_MAX_ID_TEMPLATE +
      IntToStr(nRepIndex+1), FRepositories[nRepIndex].MaxID);
  end;
end;
//------------------------------------------------------------------------------
// procedure TAppSettings.SaveWebRepositoriesSettings
//   Internal to TAppSettings.SaveSettings. Save web repositories parameters
// Parameters:
//   None
// Result:
//   None
//------------------------------------------------------------------------------
procedure TAppSettings.SaveWebRepositoriesSettings;
var
  nSrvIndex: integer;
begin
  //
  // Save web servers count
  //
  FIniFile.WriteInteger(SECTION_WEB_REPOSITORY, SERVERS_COUNT, FServersCount);
  SetLength(FServers, FServersCount);
  //
  // Save web servers info
  //
  for nSrvIndex := 0 to FServersCount - 1 do begin
    FIniFile.WriteString(SECTION_WEB_REPOSITORY, SERVER_TEMPLATE_URL +
      IntToStr(nSrvIndex+1), FServers[nSrvIndex].TemplateURL);
    FIniFile.WriteInteger(SECTION_WEB_REPOSITORY, SERVER_MIN_ID_TEMPLATE +
      IntToStr(nSrvIndex+1), FServers[nSrvIndex].MinID);
    FIniFile.WriteInteger(SECTION_WEB_REPOSITORY, SERVER_MAX_ID_TEMPLATE +
      IntToStr(nSrvIndex+1), FServers[nSrvIndex].MaxID);
  end;
end;
//------------------------------------------------------------------------------
// procedure TAppSettings.SaveGeneralAppSettings
//   Internal routine for procedure TAppSettings.SaveSettings
//     Save input|output directory pathes
// Parameters:
//   None
// Result:
//   None
//------------------------------------------------------------------------------
procedure TAppSettings.SaveGeneralAppSettings;
var
  cRelPath: AnsiString;
begin
  //
  // Application process mode variables
  //
  FIniFile.WriteBool(SECTION_GENERAL_SETTINGS, CONVERT_PATHES_TO_RELATIVE,
    FConvertPathesToRelative);
  FIniFile.WriteInteger(SECTION_GENERAL_SETTINGS, RELATIVE_CONVERSION_LEVEL,
    FRelativeRootLevel);
  //
  // Directories parameters. Convert pathes to relative, if needed.
  //
  if ConvertPathesToRelative then
    cRelPath := ConvertToRelativePath(FTempDir)
  else
    cRelPath := FTempDir;
  FIniFile.WriteString(SECTION_GENERAL_SETTINGS, TEMP_DIR, cRelPath);
  // Save application on start load|save db local flags
  //
  FIniFile.WriteBool(SECTION_GENERAL_SETTINGS, AUTOLOAD_LOCAL_DB_DUMP,
    FAutoLoadLocalDBDump);
  FIniFile.WriteBool(SECTION_GENERAL_SETTINGS, AUTOSAVE_LOCAL_DB_DUMP,
  FAutoSaveLocalDBDump);
end;
//------------------------------------------------------------------------------
// procedure TAppSettings.SaveCheckFileSettings
//   Internal for routine TAppSettings.SaveSettings only
//   Save process options variables values
// Parameters:
//   None
// Result:
//   None
//------------------------------------------------------------------------------
procedure TAppSettings.SaveCheckFileSettings;
begin
  //
  // Save process options variables values
  //
  FIniFile.WriteBool(SECTION_CHECK_OPTIONS, PROCESS_LOCAL_FILES,
    FProcessLocalFiles);
  FIniFile.WriteBool(SECTION_CHECK_OPTIONS, PROCESS_EXTRA_FILES,
    FProcessExtraFiles);
  //
  // Save check id range
  //
  FIniFile.WriteInteger(SECTION_CHECK_OPTIONS, OPTION_CHECK_START_ID,
    FCheckStartID);
  FIniFile.WriteInteger(SECTION_CHECK_OPTIONS, OPTION_CHECK_FINISH_ID,
    FCheckFinishID);
  //
  // Save specified files' checks
  //
  SaveCheckState(SECTION_CHECK_OPTIONS, OPTION_LOCAL_FILES_CHECKS, FLocalFilesChecks);
  SaveCheckState(SECTION_CHECK_OPTIONS, OPTION_EXTRA_FILES_CHECKS, FExtraFilesChecks);
end;
//------------------------------------------------------------------------------
// procedure TAppSettings.SaveCheckState
//   Convert TCheckState variable to integer and save it into ini-file
// Parameters:
//   const SectionName : AnsiString - ini-file section name
//   const ParamName : AnsiString   - parameter name
//   const Value : TCheckState      - parameter value
// Result:
//   None
//------------------------------------------------------------------------------
procedure TAppSettings.SaveCheckState(const SectionName, ParamName: AnsiString;
    const Value: TCheckState);
var
  nCheckState : Integer;
  xCheck: TCheckCondition;
  nCheckMask: Integer;
begin
  nCheckState := 0;
  //
  // Convert TCheckState value to integer
  //
  for xCheck in Value do begin
    nCheckMask := 1 shl Integer(xCheck);
    nCheckState := nCheckState + nCheckMask;
  end;
  //
  // Write data to ini-file in numerical format
  //
  FIniFile.WriteInteger(SectionName,ParamName, nCheckState);
end;
//------------------------------------------------------------------------------
// procedure TAppSettings.SaveExtraRepositorySettings
//   Internal for routine TAppSettings.SaveSettings only
//   Save process options variables values
// Parameters:
//   None
// Result:
//   None
//------------------------------------------------------------------------------
procedure TAppSettings.SaveExtraRepositorySettings;
begin
  //
  // Save extra repository settings
  //
  FIniFile.WriteString(SECTION_EXTRA_REPOSITORY, REPOSITORY_ROOT,
    ConvertToRelativePath(FExtraRepositoryRoot));
end;
//------------------------------------------------------------------------------
//  procedure TAppSettings.SaveLogFilesSettings
//    Internal to routine TAppSettings.SaveSettings only.
//    Save result filelists related parameters
// Parameters:
//   None
// Result:
//   None
//------------------------------------------------------------------------------
procedure TAppSettings.SaveLogFilesSettings;
begin
  FIniFile.WriteString(SECTION_LOG_FILES, LOG_FILE_EXIST_FILES,
    ConvertToRelativePath(FLogFileExistFiles));
  FIniFile.WriteBool(SECTION_LOG_FILES, LOG_CREATE_EXIST_FILES,
    FLogCreateExistFiles);
  //
  FIniFile.WriteString(SECTION_LOG_FILES, LOG_FILE_OUTDATED_FILES,
    ConvertToRelativePath(FLogFileOutdatedFiles));
  FIniFile.WriteBool(SECTION_LOG_FILES, LOG_CREATE_OUTDATED_FILES,
    FLogCreateOutdatedFiles);
  //
  FIniFile.WriteString(SECTION_LOG_FILES, LOG_FILE_MISSED_FILES,
    ConvertToRelativePath(FLogFileMissedFiles));
  FIniFile.WriteBool(SECTION_LOG_FILES, LOG_CREATE_MISSED_FILES,
    FLogCreateMissedFiles);
  //
  FIniFile.WriteString(SECTION_LOG_FILES, LOG_FILE_ERROR_FILESIZE,
    ConvertToRelativePath(FLogFileErrorFileSize));
  FIniFile.WriteBool(SECTION_LOG_FILES, LOG_CREATE_ERROR_FILESIZE,
    FLogCreateErrorFileSize);
  //
  FIniFile.WriteString(SECTION_LOG_FILES, LOG_FILE_ERROR_MD5,
    ConvertToRelativePath(FLogFileErrorMD5));
  FIniFile.WriteBool(SECTION_LOG_FILES, LOG_CREATE_ERROR_MD5,
    FLogCreateErrorMD5);
  //
  FIniFile.WriteString(SECTION_LOG_FILES, LOG_FILE_MISSED_FILES_URLLIST,
    ConvertToRelativePath(FLogFileMissedFilesURL));
  FIniFile.WriteBool(SECTION_LOG_FILES, LOG_CREATE_MISSED_FILES_URLLIST,
    FLogCreateMissedFilesURL);
  //
  FIniFile.WriteString(SECTION_LOG_FILES, LOG_FILE_EXTRA_FILES,
    ConvertToRelativePath(FLogFileExtraFiles));
  FIniFile.WriteBool(SECTION_LOG_FILES, LOG_CREATE_EXTRA_FILES,
    FLogCreateExtraFiles);
  //
  FIniFile.WriteString(SECTION_LOG_FILES, LOG_FILE_ERROR_ID,
    ConvertToRelativePath(FLogFileErrorID));
  FIniFile.WriteBool(SECTION_LOG_FILES, LOG_CREATE_ERROR_ID, FLogCreateErrorID);
end;
//------------------------------------------------------------------------------
// TAppSettings.SaveOutdatedRepositorySettings
//    Internal to routine TAppSettings.SaveSettings only.
//    Save outdated repository related parameters
// Parameters:
//   None
// Result:
//   None
//------------------------------------------------------------------------------
procedure TAppSettings.SaveOutdatedRepositorySettings;
begin
  //
  // Save outdated repository settings
  //
  FIniFile.WriteString(SECTION_OUTDATED_REPOSITORY, REPOSITORY_ROOT,
    ConvertToRelativePath(FOutdatedRepositoryRoot));
end;

//------------------------------------------------------------------------------
// procedure TAppSettings.SaveSettings
//   Save settings, stored in TAppSettings class, into predefined ini-file
// Parameters:
//   None
// Result:
//   None
//------------------------------------------------------------------------------
procedure TAppSettings.SaveSettings;
begin
  //
  // if FINIFile already loaded, destroy it and create new instance
  //
  if FIniFile = nil then begin
    FIniFile := TIniFile.Create(FINIFileName);
  end;
  //
  // Save app settings to ini-file
  //
  try
    //
    // Save path settings
    //
    SaveGeneralAppSettings;
    //
    // Save local repository settings
    //
    SaveLocalRepositoriesSettings;
    //
    // Save extra repository settings
    //
    SaveExtraRepositorySettings;
    //
    // Save outdated repository settings
    //
    SaveOutdatedRepositorySettings;
    //
    // Save web repository settings
    //
    SaveWebRepositoriesSettings;
    //
    // Save process options
    //
    SaveCheckFileSettings;
    //
    // Save genesis filelist settings
    //
    SaveGenesisFilelistSettings;
    //
    // Save result filelist settings
    //
    SaveLogFilesSettings;
  finally
    FIniFile.Free;
    FIniFile := nil;
  end;
end;
//------------------------------------------------------------------------------
// function TAppSettings.SelectDir
//   Show directory selection dialog and return
// Parameters:
//   var   SelectedDir : AnsiString - path to selected directory.
//                       On input - contain initial dir; on exit - selected dir
//   const DialogCaption: AnsiString - caption of selected dialog
//   const RootDir : AnsiString  - initial directory in selection dialog
//   const CanCreateDir : Boolean  - specify if you can create new dirs in dialog
// Result: Boolean
//   True, if directory is selected; False, if operation cancelled
//------------------------------------------------------------------------------
function TAppSettings.SelectDir(var SelectedDir: AnsiString; DialogCaption:
    AnsiString = ''; RootDir: AnsiString = '\'; const CanCreateDir: Boolean =
    True): Boolean;
const
  DIALOG_CAPTION_DEF = 'Select directory';
  INITIAL_DIR_DEF = '\';
var
  xOptions: TSelectDirExtOpts;
begin
  //
  // Initialize initial dir and dialog description variables
  //
  if DialogCaption = '' then
    DialogCaption := DIALOG_CAPTION_DEF;
  if (RootDir <> INITIAL_DIR_DEF) and not (DirectoryExists(RootDir))then
    RootDir := INITIAL_DIR_DEF;
  if CanCreateDir then
    xOptions := xOptions + [sdNewUI, sdValidateDir, sdNewFolder, sdShowEdit]
  else
    xOptions := xOptions + [sdNewUI, sdValidateDir];
  //
  // Execute select directory dialog, set result and exit function
  //
  Result :=
    SelectDirectory(DialogCaption, RootDir, SelectedDir, xOptions);
end;
//------------------------------------------------------------------------------
// function TAppSettings.SelectFile
//   Show file selection dialog and return selected file name
// Parameters:
//   var   FileName : AnsiString - path to selected file.
//                   On input - contain initial filepath; on exit - selected dir
//   const DialogCaption: AnsiString - caption of selected dialog
//   const RootDir : AnsiString  - initial directory in selection dialog
//   const CanCreateFile : Boolean  - specify if you can create new file in dialog
// Result: Boolean
//   True, if file is selected; False, if operation cancelled or error occured
//------------------------------------------------------------------------------
function TAppSettings.SelectFile(var FileName: AnsiString; DialogCaption:
    AnsiString = ''; RootDir: AnsiString = '\'; const CanCreateFile: Boolean =
    True): Boolean;
const
  DIALOG_CAPTION_DEF = 'Select file';
var
  dlgFileOpen: TOpenDialog;
  nIndex: integer;
begin
  Result := False;
  //
  // Initialize initial directory and dialog description variables
  //
  RootDir := ExtractFilePath(FileName);
  if not DirectoryExists(RootDir) then
    RootDir := Self.AppDir;
  if DialogCaption = '' then
    DialogCaption := DIALOG_CAPTION_DEF;
  //
  // Create exemplar of file selection dialog and
  //
  try
    dlgFileOpen := TOpenDialog.Create(nil);
    //
    dlgFileOpen.InitialDir := RootDir;
(*
  TOpenOption = (ofReadOnly, ofOverwritePrompt, ofHideReadOnly,
    ofNoChangeDir, ofShowHelp, ofNoValidate, ofAllowMultiSelect,
    ofExtensionDifferent, ofPathMustExist, ofFileMustExist, ofCreatePrompt,
    ofShareAware, ofNoReadOnlyReturn, ofNoTestFileCreate, ofNoNetworkButton,
    ofNoLongNames, ofOldStyleDialog, ofNoDereferenceLinks, ofEnableIncludeNotify,
    ofEnableSizing, ofDontAddToRecent, ofForceShowHidden);
*)
    dlgFileOpen.Options := [ofReadOnly, ofOverwritePrompt, ofNoChangeDir,
    ofExtensionDifferent, ofPathMustExist, ofFileMustExist, ofHideReadOnly,
    ofCreatePrompt, ofEnableSizing];
    Result := dlgFileOpen.Execute;
    if Result then
      FileName := dlgFileOpen.FileName;
  finally
    FreeAndNil(dlgFileOpen);
  end;
end;

procedure TAppSettings.SetCollectionFilesChecks(const Value: TCheckState);
begin
  FCollectionFilesChecks := Value;
end;

procedure TAppSettings.SetExtraFilesChecks(const Value: TCheckState);
begin
  FExtraFilesChecks := Value;
end;

procedure TAppSettings.SetExtraRepositoryRoot(const Value: AnsiString);
begin
  FExtraRepositoryRoot := Value;
end;

//------------------------------------------------------------------------------
// procedure TAppSettings.SetLogFileExtraFiles
//   Assign value to LogFileExtraFiles property
// Parameters:
//   const Value : AnsiString  - input property value
// Result: None
//------------------------------------------------------------------------------
procedure TAppSettings.SetLogFileExtraFiles(const Value: AnsiString);
begin
  FLogFileExtraFiles := Value;
end;

procedure TAppSettings.SetGenesisDBPassword(const Value: Integer);
begin
  FGenesisDBPassword := Value;
end;

procedure TAppSettings.SetLocalDBDumpFile(const Value: AnsiString);
begin
  FLocalDBDumpFile := Value;
end;

procedure TAppSettings.SetLocalFilesChecks(const Value: TCheckState);
begin
  FLocalFilesChecks := Value;
end;

procedure TAppSettings.SetLogCreateErrorID(const Value: Boolean);
begin
  FLogCreateErrorID := Value;
end;

procedure TAppSettings.SetLogCreateExistFiles(const Value: Boolean);
begin
  FLogCreateExistFiles := Value;
end;

procedure TAppSettings.SetLogCreateExtraFiles(const Value: Boolean);
begin
  FLogCreateExtraFiles := Value;
end;

procedure TAppSettings.SetLogCreateErrorFileSize(const Value: Boolean);
begin
  FLogCreateErrorFileSize := Value;
end;

procedure TAppSettings.SetLogCreateErrorMD5(const Value: Boolean);
begin
  FLogCreateErrorMD5 := Value;
end;

procedure TAppSettings.SetLogCreateMissedFiles(const Value: Boolean);
begin
  FLogCreateMissedFiles := Value;
end;

procedure TAppSettings.SetLogCreateMissedFilesURL(const Value: Boolean);
begin
  FLogCreateMissedFilesURL := Value;
end;

procedure TAppSettings.SetLogCreateOutdatedFiles(const Value: Boolean);
begin
  FLogCreateOutdatedFiles := Value;
end;

procedure TAppSettings.SetLogFileErrorID(const Value: AnsiString);
begin
  FLogFileErrorID := Value;
end;

procedure TAppSettings.SetLogFileErrorMD5(const Value: AnsiString);
begin
  FLogFileErrorMD5 := Value;
end;

procedure TAppSettings.SetLogFileMissedFiles(const Value: AnsiString);
begin
  FLogFileMissedFiles := Value;
end;

procedure TAppSettings.SetOutdatedRepositoryRoot(const Value: AnsiString);
begin
  FOutdatedRepositoryRoot := Value;
end;

procedure TAppSettings.SetProcessExtraFiles(const Value: Boolean);
begin
  FProcessExtraFiles := Value;
end;

procedure TAppSettings.SetProcessLocalFiles(const Value: Boolean);
begin
  FProcessLocalFiles := Value;
end;

//------------------------------------------------------------------------------
// procedure TAppSettings.SetRelativeRootLevel
//   Assign value to RelativeConvertionLelel property
// Parameters:
//   const Value: Integer - desired level of convertion from absolute to relative filepath   
// Result: 
//   None
//------------------------------------------------------------------------------
procedure TAppSettings.SetRelativeRootLevel(const Value: Integer);
begin
  //
  // Check if convertion level do not mismatch property value limits
  //
  if (0 <= Value) and (Value < Length(REL_PATH_TEMPLATE)) then begin
    FRelativeRootLevel := Value;
  end
  else
    FRelativeRootLevel := 0;
end;

procedure TAppSettings.SetRepositories(Value: TRepositories);
begin
  FRepositories := Value;
end;

procedure TAppSettings.SetRepositoriesCount(Value: integer);
begin
  if Value < 0 then begin
    Value := 0;
  end;
  //
  FRepositoriesCount := Value;
  SetLength(FRepositories, FRepositoriesCount);
end;

procedure TAppSettings.SetSelectFilter(const Value: AnsiString);
begin
  FSelectFilter := Value;
end;

procedure TAppSettings.SetServers(const Value: TURLServers);
begin
  FServers := Value;
end;
//
procedure TAppSettings.SetServersCount(Value: Integer);
begin
  if Value < 0 then begin
    Value := 0;
  end;
  //
  FServersCount := Value;
  SetLength(FServers, FServersCount);
end;
//==============================================================================
// Initialization unit section
//==============================================================================
initialization
  g_objSettings := nil;
end.
